/**
jQuery Logger ($.jql()) v1.0.0
Copyright (c) 2011 Joe Lu

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
jQuery.jql = function() {
    var _LEVELS = {
        'TRACE' : 2,
        'DEBUG' : 4,
        'INFO' : 6,
        'WARN' : 8,
        'ERROR' : 10,
        'FATAL' : 12,
    };
    
    var _defaults = {
        'level' : _LEVELS.INFO,
        'appender' : _getLocalAppender()
    };
    var _settings = {};
    var _level, _appender;
    var _name = null;
    var _loggers = {};
    var _instance;
    
    /**
     * Initialize jQuery Logger.
     */
    function _init() {
        _setOptions({
            'level' : _defaults.level,
            'appender' : _defaults.appender
        });
    };
    
    /**
     * Returns a appender that logs to a local console. 
     */
    function _getLocalAppender() {
        return {
            'append' : function(level, message) {
                if (console) {
                    if (level <= _LEVELS.DEBUG) {
                        console.debug(_getCurrentTime(), message);
                    } else if (level <= _LEVELS.INFO) {
                        console.info(_getCurrentTime(), message);
                    } else if (level <= _LEVELS.WARN) {
                        console.warn(_getCurrentTime(), message);
                    } else if (level <= _LEVELS.FATAL) {
                        console.error(_getCurrentTime(), message);
                    }
                }
            }
        };
    };
    
    function _getRemoteAppender() {
        return {
            'append' : function(level, message) {
                $.post(
                    _url,
                    _remoteLogDataFormatter(level, message)
                );
            }
        };
    };
    
    function _remoteLogDataFormatter(level, message) {
        
    };

    /**
     * 
     */
    function _getCurrentTime() {
        var date = new Date();
        var yyyy = date.getFullYear();
        var mm = date.getMonth() + 1;
        var dd = date.getDate();
        var hh = date.getHours();
        var min = date.getMinutes();
        var ss = date.getSeconds();

        var mysqlDateTime = yyyy + '-' + mm + '-' + dd + ' ' + hh + ':' + min + ':' + ss;

        return mysqlDateTime;
    }
    
    /**
     * Resets the logger.
     */
    function _reset() {
        _init();
    };
    
    /**
     * 
     */
    function _setOptions(options) {
        _settings = $.extend({}, _defaults, options);
        
        if (options.level) {
            _setLevel(options.level);
        }
        
        if (options.appender) {
            _setAppender(options.appender);
        }
    };
    
    /**
     * 
     */
    function _getOptions() {
        return _settings;
    };
    
    /**
     * 
     */
    function _setName(name) {
        _name = name;
    };
    
    /**
     * 
     */
    function _getName() {
        return _name;
    };
    
    /**
     * 
     */
    function _setLevel(level) {
        _level = level;
    };
    
    /**
     * 
     */
    function _getLevel() {
        return _level;
    };
    
    /**
     * 
     */
    function _setAppender(appender) {
        if (appender && appender.append) {
            _appender = appender;
        } else {
            throw 'Invalid appender.  Appender must have append() method.';
        }
    };
    
    /**
     * 
     */
    function _getAppender() {
        return _appender;
    };
    
    /**
     * 
     */
    function _getLogger(name) {
        if (!_loggers[name]) {
            var logger = _instance();
            logger.setName(name);
            // Delete getLogger() function for all other logger instances
            delete logger['getLogger'];
            
            _loggers[name] = logger;
        }
        
        return _loggers[name];
    };
    
    /**
     * 
     */
    function _log(level, message) {
        return function(message) {
            if (level >= _level) {
                if (_name) {
                    message = _name + '::' + message;
                }
                _appender.append(level, message);
            }
        }
    };
    
    // The API of jQuery Logger
    var _api = {
        'setOptions' : _setOptions,
        'getOptions' : _getOptions,
        'setAppender' : _setAppender,
        'getAppender' : _getAppender,
        'setLevel' : _setLevel,
        'getLevel' : _getLevel,
        'setName' : _setName,
        'getName' : _getName,
        'getLogger' : _getLogger,
        'reset' : _reset
    };
    
    // Adds all the log levels and corresponding logging methods to _api object.
    for (var level in _LEVELS) {
        _api[level] = _LEVELS[level];
        _api[level.toLowerCase()] = _log(_LEVELS[level]);
    }
    
    _init();
    
    // Store current instnace for cloning
    _instance = arguments.callee;
    
    return _api;
}();